home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Graphics / Viewers / aa_m68k_Intel_Only / ToyViewer1.2 / Source / ToyWinSave.m < prev    next >
Encoding:
Text File  |  1995-11-12  |  6.6 KB  |  293 lines

  1. #import "ToyWin.h"
  2. #import <appkit/Application.h>
  3. #import <appkit/publicWraps.h>
  4. #import <appkit/SavePanel.h>
  5. #import <appkit/NXImage.h>
  6. #import <appkit/NXBitmapImageRep.h>
  7. #import <appkit/NXEPSImageRep.h>
  8. #import <appkit/Control.h>
  9. #import  <objc/NXBundle.h>    /* LocalizedString */
  10. #import <appkit/Panel.h>
  11. #import <appkit/tiff.h>
  12. #import <streams/streams.h> // NXStream
  13. #import <stdio.h>
  14. #import <stdlib.h>
  15. #import <string.h>
  16. #import <libc.h>
  17. #import "ToyView.h"
  18. #import "TVController.h"
  19. #import "TiffSavePanel.h"
  20. #import "common.h"
  21. #import "save.h"
  22.  
  23. @implementation ToyWin (ImageSave)
  24.  
  25. static char *mk_tmpname(const char *s, const char *ex, BOOL nopath)
  26. {
  27.     static char    srcfn[MAXFILENAMELEN];
  28.     int    i, j;
  29.  
  30.     if (nopath) {
  31.         for (i = j = 0; s[i]; i++)
  32.             if (s[i] == '/') j = i + 1;
  33.     }else
  34.         j = 0;
  35.     strcpy(srcfn, s + j);
  36.     for (i = j = 0; srcfn[i]; i++)
  37.         if (srcfn[i] == '.') j = i + 1;
  38.     if (j == 0)
  39.         srcfn[i] = '.',  j = i + 1;
  40.     while (*ex)
  41.         srcfn[j++] = *ex++;
  42.     srcfn[j] = 0;
  43.     return srcfn;
  44. }
  45.  
  46.  
  47. static char saveDir[MAXFILENAMELEN];
  48.  
  49. - (char *)getSavename: (const char *)path with:(int)itype
  50. {
  51.     SavePanel *savePanel;
  52.     char    *stmp, *sav = NULL;
  53.     const char *ex = NULL;
  54.  
  55.     switch (itype) {
  56.     case Type_eps: ex = "eps";  break;
  57.     case Type_bmp: ex = "bmp";  break;
  58.     case Type_gif: ex = "gif";  break;
  59.     case Type_ppm: ex = "pnm";  break;
  60.     }
  61.     stmp = mk_tmpname(path, ex, YES);
  62.     if (!saveDir[0])
  63.         strcpy(saveDir, getenv("HOME"));
  64.     savePanel = [SavePanel new];
  65.     if ([savePanel runModalForDirectory: saveDir file: stmp]) {
  66.         sav = mk_tmpname([savePanel filename], ex, NO);
  67.         if (sav == NULL || *sav == 0)
  68.             return NULL;
  69.         strcpy(saveDir, [savePanel directory]);
  70.     }
  71.     return sav;
  72. }
  73.  
  74. - (char *)getSaveTiffname: (const char *)path jpeg: (BOOL)flag
  75.     compress: (int *)type by: (float *)factor
  76. {
  77.     TiffSavePanel *savePanel;
  78.     char    *stmp, *sav = NULL;
  79.     static    float jpegFactor = 10.0; /* Default */
  80.  
  81.     stmp = mk_tmpname(path, "tiff", YES);
  82.     if (!saveDir[0])
  83.         strcpy(saveDir, getenv("HOME"));
  84.     savePanel = [[TiffSavePanel new] init: jpegFactor jpeg: flag];
  85.     if ([savePanel runModalForDirectory: saveDir file: stmp]) {
  86.         sav = mk_tmpname([savePanel filename], "tiff", NO);
  87.         if (sav == NULL || *sav == 0)
  88.             return NULL;
  89.         strcpy(saveDir, [savePanel directory]);
  90.         [savePanel compressType: type with: factor];
  91.         if (*type == NX_TIFF_COMPRESSION_JPEG)
  92.             jpegFactor = *factor;
  93.     }
  94.     return sav;
  95. }
  96.  
  97. - saveAsTiff: sender
  98. {
  99.     NXStream *stream;
  100.     int    fd = -1;
  101.     char    *sav;
  102.     commonInfo *cinf;
  103.     NXBitmapImageRep *rep;
  104.     BOOL    jflag;
  105.     int    type;
  106.     float    factor;
  107.  
  108.     cinf = [[self toyView] commonInfo];
  109.     rep = (NXBitmapImageRep *)[[[self toyView] image] bestRepresentation];
  110.     jflag = (cinf->bits > 2  /* && cinf->type != Type_eps */
  111.         && [rep canBeCompressedUsing: NX_TIFF_COMPRESSION_JPEG]);
  112.     sav = [self getSaveTiffname: imageFilename jpeg: jflag
  113.         compress: &type by: &factor];
  114.     if (sav == NULL) /* canceled */
  115.         return self;
  116.     if ((fd = open(sav, O_WRONLY|O_CREAT|O_TRUNC, 0644)) < 0
  117.     || (stream = NXOpenFile(fd, NX_WRITEONLY)) == NULL) {
  118.         if (fd >= 0) (void) close(fd);
  119.         errAlert(sav, Err_SAVE);
  120.         return self;
  121.     }
  122.     if (factor < 1.0) factor = 1.0;
  123.     else if (factor > 255.0) factor = 255.0;
  124.     [rep writeTIFF:stream usingCompression:type andFactor:factor];
  125.     NXClose(stream);
  126.     (void)close(fd);
  127.     return self;
  128. }
  129.  
  130. - saveAsEPS: sender
  131. {
  132.     NXStream *stream;
  133.     char    *sav;
  134.     id    tv;
  135.     NXRect    rect;
  136.  
  137.     sav = [self getSavename: imageFilename with:Type_eps];
  138.     if (sav == NULL) /* canceled */
  139.         return self;
  140.     stream = NXOpenMemory(NULL, 0, NX_WRITEONLY);
  141.     if (stream == NULL) {
  142.         errAlert(sav, Err_MEMORY);
  143.         return self;
  144.     }
  145.     tv = [self toyView];
  146.     [tv getFrame:&rect];
  147.     [tv copyPSCodeInside:&rect to:stream];
  148.     NXFlush(stream);
  149.     if (NXSaveToFile(stream, sav))
  150.         errAlert(sav, Err_SAVE);
  151.     NXCloseMemory(stream, NX_FREEBUFFER);
  152.     return self;
  153. }
  154.  
  155.  
  156. /* Local Method */
  157. - saveFullColor:(FILE *)fp info:(commonInfo *)cinf
  158.     colors:(int)cnum type:(int)itype map:(unsigned char **)map
  159. {
  160.     const char *ask, *full, *reduce;
  161.     paltype *pal = NULL;
  162.     char msg[64];
  163.     float bright;
  164.  
  165.     if (itype == Type_bmp) {
  166.         ask = NXLocalizedString("Reduce Color?", NULL, BMP_Reduction);
  167.         full = NXLocalizedString("Leave", NULL, BMP_Leave);
  168.         reduce = NXLocalizedString("Reduce", NULL, BMP_Reduce);
  169.         if (NXRunAlertPanel("", ask, full, reduce, NULL)) {
  170.             saveBmpbmap(fp, cinf, cnum, NULL, map);
  171.             return self;
  172.         }
  173.     }else /* gif */ {
  174.         ask = NXLocalizedString("Reduction Start",
  175.                 NULL, GIF_Reduction);
  176.         (void) NXRunAlertPanel("", ask, NULL, NULL, NULL);
  177.     }
  178.  
  179.     [messagePanel makeKeyAndOrderFront: self];
  180.     [messageText setStringValue:"Trying Reduction..."];
  181.     [messagePanel setFloatingPanel: YES];
  182.     NXPing();
  183.     for ( bright = 0.0; ; ) {
  184.         if (reduce_bright(&cnum, &bright, map)) break;
  185.         sprintf(msg, "Trying Reduction: Brightness %d%%",
  186.             (int)(bright * 100.0));
  187.         [messageText setStringValue: msg];
  188.         NXPing();
  189.     }
  190.     [messageText setStringValue: "Making Palette..."];
  191.     NXPing();
  192.     pal = get256map(&cnum);
  193.     [messageText setStringValue: "Writing Image..."];
  194.     NXPing();
  195.     if (itype == Type_bmp)
  196.         saveBmpbmap(fp, cinf, cnum, pal, map);
  197.     else {
  198.         resetPixel(map, 0);
  199.         GIFEncode(fp, cinf, cnum, pal);
  200.     }
  201.     [messagePanel setFloatingPanel: NO];
  202.     [messagePanel close];
  203.  
  204.     return self;
  205. }
  206.  
  207.  
  208. - (int)getBitmap:(unsigned char **)map info:(commonInfo **)infp
  209. {
  210.     NXImageRep *rep;
  211.     rep = [[[self toyView] image] bestRepresentation];
  212.     [(NXBitmapImageRep *)rep getDataPlanes: map];
  213.     return 0;
  214. }
  215.  
  216. - freeTempBitmap
  217. {
  218.     return self;
  219. }
  220.  
  221. - saveAs: (int)itype
  222. {
  223.     FILE    *fp;
  224.     char    *sav;
  225.     commonInfo *cinf;
  226.     unsigned char *map[5];
  227.     int    cnum, err;
  228.  
  229.     cinf = [[self toyView] commonInfo];
  230.     if (cinf->cspace == NX_CMYKColorSpace) {
  231.         errAlert(imageFilename, Err_SAV_IMPL);
  232.         return self;
  233.     }
  234.  
  235.     sav = [self getSavename: imageFilename with: itype];
  236.     if (sav == NULL) /* canceled */
  237.         return self;
  238.     if ((fp = fopen(sav, "w")) == NULL) {
  239.         errAlert(sav, Err_SAVE);
  240.         return self;
  241.     }
  242.  
  243.     err = [self getBitmap:map info: &cinf];
  244.  
  245.     if (err == 0 && (err = initGetPixel(cinf)) == 0) {
  246.         if (itype == Type_ppm) {
  247.             resetPixel(map, 0);
  248.             if ((err = ppmwrite(fp, cinf, map)) == 0)
  249.                 goto EXIT;
  250.         }else {
  251.             if (cinf->palette) {
  252.                 err = getAllPalColor();
  253.                 cnum = cinf->palsteps;
  254.             }else
  255.                 err = getAllColor(&cnum, map);
  256.         }
  257.     }
  258.     if (err) {
  259.         errAlert(sav, err);
  260.         (void)fclose(fp);
  261.         (void)unlink(sav);
  262.         return self;
  263.     }
  264.  
  265.     if (cnum > FIXcount) /* bmp / gif */
  266.         [self saveFullColor: fp
  267.             info: cinf colors: cnum type: itype map: map];
  268.     else {
  269.         paltype *pal = cinf->palette;
  270.         if (pal == NULL)
  271.             pal = getNormalmap(&cnum);
  272.         if (itype == Type_bmp)
  273.             saveBmpbmap(fp, cinf, cnum, pal, map);
  274.         else {
  275.             resetPixel(map, 0);
  276.             GIFEncode(fp, cinf, cnum, pal);
  277.         }
  278.     }
  279. EXIT:
  280.     free256map();
  281.     (void)fclose(fp);
  282.     [self freeTempBitmap];
  283.     return self;
  284. }
  285.  
  286. - print: sender
  287. {
  288.     [[self toyView] printPSCode:sender];
  289.     return self;
  290. }
  291.  
  292. @end
  293.